package com.newbie.pet.util;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.newbie.pet.model.AuthUser;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * 类描述：本地缓存
 *
 * @author zhangkailiang
 * @date 2020/5/23
 */
@Slf4j
public class UserUtil {
    /**
     * 用户名 -> 用户信息
     */
    private static LoadingCache<String, AuthUser> authUser;
    /**
     * 用户名 + token -> 用户名
     */
    private static LoadingCache<String, String> username;
    /**
     * 本地线程-用户信息，为了方便获取用户信息
     */
    private static ThreadLocal<AuthUser> threadLocal;
    /**
     * 缓存最大条数
     */
    private static final int MAXIMUM_SIZE = 300;
    /**
     * 缓存最长时间
     */
    private static final int MAXIMUM_TIME = 30;

    static {
        authUser = Caffeine.newBuilder()
                .maximumSize(MAXIMUM_SIZE)
                .expireAfterAccess(MAXIMUM_TIME, TimeUnit.DAYS)
                .build(key -> null);

        username = Caffeine.newBuilder()
                .maximumSize(MAXIMUM_SIZE * 10)
                .expireAfterAccess(MAXIMUM_TIME, TimeUnit.HOURS)
                .build(key -> null);

        threadLocal = new ThreadLocal<>();
        log.info("Local Cache Init");
    }

    /**
     * 获取本地缓存用户信息
     */
    public static AuthUser getValue(String name, String token) {
        String myName = username.get(getKey(name, token));
        if (myName == null) {
            return null;
        }
        return authUser.get(myName);
    }

    /**
     * 设置本地缓存用户信息
     */
    public static void setValue(String name, String token, AuthUser value) {
        authUser.put(name, value);
        username.put(getKey(name, token), name);
        setAuthUser(value);
    }

    /**
     * 设置本地缓存key
     */
    public static String getKey(String username, String token) {
        return username + ":" + token;
    }

    /**
     * 获取本地线程中的用户信息
     */
    public static AuthUser getAuthUser() {
        return threadLocal.get();
    }

    /**
     * 获取指定用户
     */
    public static AuthUser getAuthUser(String username) {
        return authUser.get(username);
    }

    /**
     * 获取本地线程中的门户ID
     */
    public static Long getUserId() {
        AuthUser authUser = threadLocal.get();
        return authUser.getUserId();
    }

    /**
     * 设置本地线程中的用户信息
     */
    public static void setAuthUser(AuthUser value) {
        threadLocal.set(value);
    }

    /**
     * 清理本地线程中的用户信息
     */
    public static void clearAuthUser() {
        threadLocal.remove();
    }
}
